package com.grm.flowable.service;

import com.grm.common.Result;
import com.grm.flowable.entity.ApproveRejectVO;
import com.grm.flowable.entity.AskForLeave;
import com.grm.flowable.entity.HistoryInfo;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class AskForLeaveService {
    @Autowired
    RuntimeService runtimeService;
    @Autowired
    TaskService taskService;
    @Autowired
    HistoryService historyService;

    @Transactional
    public Result askForLeave(AskForLeave askForLeave) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("name", askForLeave.getName());
        variables.put("days", askForLeave.getDays());
        variables.put("reason", askForLeave.getReason());
        try {
            /*
            String processDefinitionKey: 流程引擎的名字，这就是我们刚才在流程的 XML 文件中定义的名字。
             String businessKey: 表示当前这个流程的 key，我用了申请人的名字，将来我们可以通过申请人的名字查询这个人曾经提交的所有申请流程。
             Map<String, Object> variables: 传递的变量（提交的表单内容）
             */
            runtimeService.startProcessInstanceByKey
                    ("holidayRequest", askForLeave.getName(), variables);
            return Result.success("已提交请假申请");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failed(500,"提交申请失败");
    }

    public List<Map<String, Object>> leaveList(String identity) {
        // 审批组查出需要审批的任务
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(identity).list();
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < tasks.size(); i++) {
            Task task = tasks.get(i);
            Map<String, Object> variables = taskService.getVariables(task.getId());
            variables.put("id", task.getId());
            list.add(variables);
        }
        return list;
    }

    public Result askForLeaveHandler(ApproveRejectVO approveRejectVO) {
        try {
            boolean approved = approveRejectVO.getApprove();
            Map<String, Object> variables = new HashMap<>();
            variables.put("approved", approved);
            variables.put("employee", approveRejectVO.getName());
            Task task = taskService.createTaskQuery().taskId(approveRejectVO.getTaskId()).singleResult();
            taskService.complete(task.getId(), variables);
            if (approved) {
                //如果是同意，还需要继续走一步
                Task t = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                //taskService.complete 方法传入 taskId 和 变量，以使流程向下走
                taskService.complete(t.getId());
            }
            return Result.success("操作成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.failed(500,"操作失败");
    }

    public Result searchResult(String name) {
        List<HistoryInfo> historyInfos = new ArrayList<>();
        // createHistoricProcessInstanceQuery 用来查询历史流程
        //查询的时候还加上了 finished 方法，这个表示要查询的流程必须是执行完毕的流程，
        // 对于没有执行完毕的流程，这里不查询，查完之后，按照流程最后的处理时间进行排序。
        List<HistoricProcessInstance> historicProcessInstances =
                historyService.createHistoricProcessInstanceQuery()
                        .processInstanceBusinessKey(name)
                        .finished()
                        .orderByProcessInstanceEndTime()
                        .desc()
                        .list();
        //从 HistoricProcessInstance 中提取出每一个流程的详细信息，并存入到集合中，并最终返回。
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
            HistoryInfo historyInfo = new HistoryInfo();
            Date startTime = historicProcessInstance.getStartTime();
            Date endTime = historicProcessInstance.getEndTime();
            // createHistoricVariableInstanceQuery 则主要是用来查询流程变量的。
            List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery()
                    .processInstanceId(historicProcessInstance.getId())
                    .list();
            for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
                String variableName = historicVariableInstance.getVariableName();
                Object value = historicVariableInstance.getValue();
                if ("reason".equals(variableName)) {
                    historyInfo.setReason((String) value);
                } else if ("days".equals(variableName)) {
                    historyInfo.setDays(Integer.parseInt(value.toString()));
                } else if ("approved".equals(variableName)) {
                    historyInfo.setStatus((Boolean) value);
                } else if ("name".equals(variableName)) {
                    historyInfo.setName((String) value);
                }
            }
            historyInfo.setStartTime(startTime);
            historyInfo.setEndTime(endTime);
            historyInfos.add(historyInfo);
        }
        return Result.success("ok", historyInfos);
    }
}
